<template>
    <div class="page_root" :key="queryUpdateFlag" data-page-name="计划调整" data-page-identification="p_8t3wjr0rgr">
        <a-spin :spinning="pageLoading.loading" :tip="pageLoading.tip" />
        <!--        计划变更弹窗-->
        <div class="body">
            <template v-if="useType === '计划调整'">
                <div class="kb-table-box">
                    <a-table
                        bordered
                        :columns="planChangeColumns"
                        :data-source="state.planChangeDataSource"
                        :pagination="false"
                    >
                        <template #bodyCell="{ record, text, column, index }">
                            <template v-if="column.dataIndex == 'endTime'">
                                <a-date-picker
                                    @change="reloadData(record)"
                                    value-format="YYYY-MM-DD"
                                    v-model:value="record.endTime"
                            /></template>
                            <template v-if="column.dataIndex == 'startTime'">
                                <a-date-picker
                                    @change="reloadData(record)"
                                    value-format="YYYY-MM-DD"
                                    v-model:value="record.startTime"
                                />
                            </template>
                        </template>
                    </a-table>
                </div>
                <div class="tip-title">附件</div>
                <a-form-item>
                    <a-upload
                        v-model:file-list="state.planChangeFileList"
                        :multiple="true"
                        :before-upload="handlerResolvedUpload"
                        @remove="handlerResolvedRemove"
                        accept=".xlsx, image/*,.docx,, .xls,.mp4"
                    >
                        <a-button type="primary">
                            <upload-outlined />
                            上传
                        </a-button>
                    </a-upload>
                </a-form-item>
                <div class="tip-title">备注</div>

                <a-textarea v-model:value="state.description" />
                <div style="display: flex; justify-content: center">
                    <div class="bottom-btn">
                        <a-button type="primary" ghost @click="callParentMethod">取消</a-button>
                        <a-button type="primary" @click="submitPlanChange" :loading="state.submitPlangeLoading"
                            >提交</a-button
                        >
                    </div>
                </div>
            </template>
            <template v-if="useType === '查看计划'">
                <div class="kb-table-box">
                    <a-table
                        bordered
                        :columns="showChangeColumns"
                        :data-source="state.showChangeDataSource"
                        :scroll="{ x: 2000 }"
                        :pagination="false"
                    >
                        <template #bodyCell="{ record, text, column, index }">
                            <template v-if="column.dataIndex == 'attachmentList'">
                                <a
                                    href="#"
                                    v-for="(item, index) in record.attachmentList"
                                    @click="handlerDownload(item)"
                                >
                                    {{ item.name }}</a
                                >
                            </template>
                            <!-- 渲染阶段字段（包含换行） -->
                            <template v-else-if="typeof column.customRender === 'function'">
                                <div style="white-space: pre-line; text-align: center">
                                    {{ column.customRender({ record }) }}
                                </div>
                            </template>
                        </template>
                    </a-table>
                </div>
            </template>
        </div>
        <!--        计划变更弹窗-->
    </div>
</template>
<script setup lang="tsx">
    import {
        h,
        ref,
        reactive,
        toRaw,
        markRaw,
        watch,
        computed,
        onBeforeMount,
        onMounted,
        onBeforeUnmount,
        onUnmounted,
        onActivated,
        onDeactivated
    } from 'vue'
    import { useRoute, useRouter } from 'vue-router'
    const router = useRouter()
    const route = useRoute()
    import { get, post, put, del, request, requestWithHeaders } from '@/utils/http/Axios'
    import {
        cloneDeep,
        localGet,
        merge,
        getDifferenceArray,
        traversalTreeStructure,
        checkCaseCondition,
        renderStringInTemplate,
        handleBreadcrumbJump,
        throttle,
        permission,
        getComponentParamsValue
    } from '@/utils/index'
    import { isNullOrEmpty, isEmptyArr, isNullOrUnDef, isContained, isArray, isEmpty, isObject } from '@/utils/is'
    import dayjs from 'dayjs'
    import { getPagePcChartsDataSourceConvert } from '@/utils/chart'
    import { message, notification, Modal } from 'ant-design-vue'
    import {
        propertyFormatByNumber,
        propertyFormatByPercentage,
        propertyFormatByDate,
        parseSubFromDataList
    } from '@/utils/format'
    import colorTheme from '@/design/custom-theme.json'
    /*** PUBLISH_EXEGESIS ***
 import UserTableRecords from '@/model/UserTableRecords';
 import { getAppBaseUrl } from '@/utils/index';
 import { sendToken } from "@/hooks/useIframeToken";
 import { useSystemStore } from "@/store/modules/system";
 const systemStore = useSystemStore();
 *** PUBLISH_EXEGESIS ***/

    // 获取传入的流程ID和组件参数
    const props = defineProps({
        'processInstanceId': {
            type: [String, Number, Boolean],
            default: undefined
        },
        'id': {
            type: [String, Number],
            default: undefined
        },
        'projectId': {
            type: [String, Number],
            default: undefined
        },
        'type': {
            type: [String],
            default: undefined
        },
        'from': {
            type: [String],
            default: undefined
        }
    })
    const immediateWatch = (source, callback) => {
        watch(source, callback, { deep: true, immediate: true })
    }

    /* -------------------------- 属性定义 -------------------------- */

    const setTimeOutList = []
    const pageLoading = reactive({
        loading: false,
        tip: undefined
    })
    const authInfo = localGet('app-user-store')

    // 处理校验
    const setSubFormName = (parentInfo, name) => {
        return [parentInfo.parents, parentInfo.cycleIndex, name]
    }

    /* ========================== 属性定义 ========================== */

    /* -------------------------- 元素数据引用 -------------------------- */

    /* ========================== 元素数据引用 ========================== */

    /* -------------------------- 页面数据 -------------------------- */

    /* ========================== 页面数据 ========================== */

    /* -------------------------- 响应 -------------------------- */

    /* ========================== 响应 ========================== */

    /* -------------------------- 函数 -------------------------- */

    /* ========================== 函数 ========================== */

    /* -------------------------- 页面参数 -------------------------- */

    const pageParameter_state = reactive({
        'processInstanceId': props.processInstanceId ?? route.query.processInstanceId
    })

    /* ========================== 页面参数 ========================== */

    /* -------------------------- 组件事件处理方法 -------------------------- */

    // ---------------------------- 组件数据同步 ----------------------------

    // ============================ 组件数据同步 ============================

    /* ========================== 组件事件处理方法 ========================== */

    /* -------------------------- 生命周期 -------------------------- */
    // 用于参数变更后重新执行自定义指令
    const queryUpdateFlag = ref(0)
    onMounted(() => {})

    onUnmounted(() => {
        // 销毁定时器
        setTimeOutList.forEach(({ repeat, timer }) => {
            repeat ? clearInterval(timer) : clearTimeout(timer)
        })
    })

    /* ========================== 生命周期 ========================== */

    /* -------------------------- 数据关联处理 -------------------------- */

    /* -------------------------- 表单数据同步 -------------------------- */
    /* ========================== 表单数据同步 ========================== */

    /* ========================== 数据关联处理 ========================== */

    /* -------------------------- 不同组件自定义的处理逻辑 -------------------------- */

    /* ========================== 不同组件自定义的处理逻辑 ========================== */

    // ================================定制化逻辑========================================
    const useId = ref()
    const useFrom = ref()
    const useType = ref()
    const useProjectId = ref()
    const { id, type, from, projectId } = props
    import { watchEffect } from 'vue'
    watchEffect(() => {
        if (props.id || props.type || props.from) {
            setTimeout(() => {
                useId.value = props.id
                useFrom.value = props.from
                useType.value = props.type
                useProjectId.value = props.projectId
                if (useType.value === '计划调整') {
                    getPlanChange()
                } else {
                    getShowChange()
                }
            }, 500)
        }
    })
    const state = reactive({
        planChangeDataSource: [],
        showChangeDataSource: [],
        planChangeFileList: [],
        description: undefined,
        submitPlangeLoading: false
    })
    const timesMap = [
        // { label: '原计划开始', field: 'originStartTime' },
        { label: '预计开始', field: 'startTime' },
        // { label: '原计划结束', field: 'originEndTime' },
        { label: '预计结束', field: 'endTime' }
    ]

    // 生成阶段列
    function generateStageColumns(stageList) {
        return stageList.map((stage, index) => ({
            title: stage.stageName,
            children: [
                {
                    title: '预计开始',
                    align: 'center',
                    width: 150,
                    dataIndex: `infoList[${index}]`,
                    customRender: ({ record }) => {
                        const item = record.infoList?.[index]
                        return item ? `变更前：${item.originStartTime || '-'}\n变更后：${item.startTime || '-'}` : '-'
                    }
                },
                {
                    title: '预计结束',
                    align: 'center',
                    width: 150,
                    dataIndex: `infoList[${index}]`,
                    customRender: ({ record }) => {
                        const item = record.infoList?.[index]
                        return item ? `变更前：${item.originEndTime || '-'}\n变更后：${item.endTime || '-'}` : '-'
                    }
                }
            ]
        }))
    }

    const planChangeColumns = ref([
        {
            title: '里程碑项目阶段',
            dataIndex: 'stageName',

            ellipsis: true,
            align: 'center',
            width: 80
        },
        {
            title: '原预计开始',
            dataIndex: 'originStartTime',

            ellipsis: true,
            align: 'center',
            width: 80
        },
        {
            title: '原预计结束',
            dataIndex: 'originEndTime',

            ellipsis: true,
            align: 'center',
            width: 80
        },
        {
            title: '新预计开始',
            dataIndex: 'startTime',

            ellipsis: true,
            align: 'center',
            width: 80
        },
        {
            title: '新预计结束',
            dataIndex: 'endTime',

            ellipsis: true,
            align: 'center',
            width: 80
        }
    ])
    const showChangeColumns = ref([
        {
            title: '变更人',
            dataIndex: 'submitter',
            ellipsis: true,
            fixed: 'left',
            align: 'center',
            width: 120
        },
        {
            title: '变更时间',
            dataIndex: 'submissionTime',
            ellipsis: true,
            align: 'center',
            fixed: 'left',
            width: 180
        },

        {
            title: '附件',
            dataIndex: 'attachmentList',
            ellipsis: true,
            align: 'center',
            width: 180
        },
        {
            title: '备注',
            dataIndex: 'remarks',

            ellipsis: true,
            align: 'center',
            width: 80
        }
    ])
    const date = ref('2025-06-23')
    function timeChange(o, n) {
        console.log('变了')
        console.log(n, 'n')
        console.log(o, 'o')
    }
    import { inject } from 'vue'

    const parentMethod = inject('parentMethod')

    function callParentMethod() {
        if (typeof parentMethod === 'function') {
            parentMethod()
        } else {
            console.error('Parent method not provided')
        }
    }
    // 上传文件
    function handlerResolvedUpload(file) {
        const data = new FormData()
        data.append('file', file)

        post('/file-storage/api/v1/file/upload', data)
            .then(({ data: { fullUrl } }) => {
                if (data) {
                    // 新文件对象
                    const newFile = {
                        uid: file.uid,
                        lastModified: file.lastModified,
                        name: file.name,
                        size: file.size,
                        type: file.type,
                        status: 'done',
                        url: fullUrl
                    }

                    // 去重，保留一个副本
                    state.planChangeFileList = [
                        // 保留已存在文件（去除重复）
                        ...state.planChangeFileList.filter(item => item.uid !== file.uid && item.name !== file.name),
                        // 添加新的文件
                        newFile
                    ]
                }
            })
            .catch(e => {
                message.error('上传失败' + e)
            })

        return false
    }
    // 移除文件
    function handlerResolvedRemove(file) {
        state.planChangeFileList = state.planChangeFileList.filter(item => item.uid !== file.uid)
    }
    function getPlanChange() {
        get(
            `/solution-ppm/api/v2/built-in-system-ppm/project_progress/stage_adjust/expect/${useFrom.value}/${useProjectId.value}`
        ).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                state.planChangeDataSource = []
                return
            }
            state.planChangeDataSource = data.data
        })
    }
    // 刷新数据
    function reloadData() {
        put(`/solution-ppm/api/v2/built-in-system-ppm/project_progress/stage_adjust/expect`, {
            productLine: useFrom.value,
            infoList: state.planChangeDataSource
        }).then(data => {
            state.planChangeDataSource = data.data.infoList
        })
    }
    function submitPlanChange() {
        state.submitPlangeLoading = true
        post('/solution-ppm/api/v2/built-in-system-ppm/project_progress/stage_adjust/expect/approve', {
            projectId: useProjectId.value,
            productLine: useFrom.value,
            infoList: state.planChangeDataSource,
            attachmentList: state.planChangeFileList,
            remarks: state.description
        })
            .then(data => {
                if (data.code !== 200) {
                    message.error(data.message)
                    return
                }
                message.success(data.message)
                callParentMethod()
            })
            .finally(() => {
                state.submitPlangeLoading = false
            })
    }
    function getShowChange() {
        get(
            `/solution-ppm/api/v2//built-in-system-ppm/project_progress/stage_adjust/expect/approve_list/${useProjectId.value}`
        ).then(data => {
            if (data.code !== 200) {
                message.error(data.message)
                state.showChangeDataSource = []
                return
            }
            if (data.data[0].infoList && data.data[0].infoList.length > 0) {
                // 1. 生成动态阶段列
                const stageColumns = generateStageColumns(data.data[0].infoList)

                // 2. 找到 "项目阶段" 列的索引
                const fileIndex = showChangeColumns.value.findIndex(col => col.dataIndex === 'attachmentList')

                // 3. 在 "项目阶段" 列之前插入动态列
                showChangeColumns.value.splice(fileIndex, 0, ...stageColumns)
                console.log(showChangeColumns.value)
            }

            state.showChangeDataSource = data.data
        })
    }
    function handlerDownload(item) {
        fetch(item.url)
            .then(response => response.blob())
            .then(blob => {
                const downloadLink = document.createElement('a')
                const url = URL.createObjectURL(blob)
                downloadLink.href = url
                downloadLink.setAttribute('download', item.name)
                downloadLink.style.display = 'none'
                document.body.appendChild(downloadLink)
                downloadLink.click()
                document.body.removeChild(downloadLink)

                // Release the object URL after the download
                URL.revokeObjectURL(url)
            })
            .catch(err => {
                console.error('Download failed', err)
            })
    }
</script>
<style lang="less" scoped>
    .page_root {
        width: 100%;
        height: 100%;
        overflow: auto;
    }
    .page_root :deep(.@{ant-prefix}-spin-nested-loading),
    .page_root :deep(.@{ant-prefix}-spin-container) {
        height: 100%;
    }
    .page_root :deep(.@{ant-prefix}-spin-container .@{ant-prefix}-table-wrapper) {
        display: flex;
        flex-flow: column nowrap;
        justify-content: flex-start;
    }
    .page_root :deep(.@{ant-prefix}-table) {
        flex: auto;
        overflow: auto;
    }
    .table-moreBtn_down {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        width: 100px;
    }

    .table-moreBtn_menu :deep(.table-moreBtn_menu-item):hover {
        background: #ebf1ff;
    }

    /*  表格树结构样式处理，展开按钮层级增加*/
    :deep(.@{ant-prefix}-table-row-expand-icon) {
        z-index: 1;
    }
    /*  表格树结构 由于每个表格项采用自定义组件，使用绝对定位布局，开启树结构导致显示异常，暂时使用层级定位位置 */
    :deep(.@{ant-prefix}-table-row-level-1 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 15px !important;
        width: calc(100% - 15px);
    }
    :deep(.@{ant-prefix}-table-row-level-2 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 30px !important;
        width: calc(100% - 30px);
    }
    :deep(.@{ant-prefix}-table-row-level-3 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 45px !important;
        width: calc(100% - 45px);
    }
    :deep(.@{ant-prefix}-table-row-level-4 .@{ant-prefix}-table-cell-with-append .cell-wrapper-left) {
        left: 60px !important;
        width: calc(100% - 60px);
    }

    /* 穿梭框改变默认样式，为根据组件样式控制左右栏宽度。 */
    :deep(.@{ant-prefix}-transfer-list) {
        height: 100%;
        width: 50%;
    }
    /*样式*/
    .body {
        height: 100%;
        background-color: #fff;
    }
    .kb-table-box {
        margin-bottom: 16px;
        border-radius: 2px;
        background-color: #fff;
    }
    .kb-table-box:deep(.@{ant-prefix}-table-thead) > tr > th {
        background: #3875ff;
        color: #fff;
        font-weight: 600;
        padding: 8px 16px;
        border-right: 1px solid #d9d9d9 !important;
        position: relative;
    }
    .kb-table-box :deep(.@{ant-prefix}-table-tbody) tr > td {
        font-size: 14px;
        font-family: arial, helvetica, 'microsoft yahei';
        font-weight: 400;
        color: #262626;
        border-bottom: 1px solid #d9d9d9;
        padding: 8px 8px;
        word-break: break-all;
    }
    .tip-title {
        font-size: 16px;
        color: #262626;
        letter-spacing: 0;
        font-weight: 600;
        line-height: 16px;
        padding-left: 8px;
        border-left: 4px solid #3875ff;
        height: 16px;
        margin-bottom: 16px;
    }
    .bottom-btn {
        width: 10%;
        margin-top: 16px;
        display: flex;
        justify-content: space-around;
    }
    /*样式*/
</style>
